package com.shi.desktop.indexer;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXXMLHandler extends DefaultHandler implements DocumentHandler {

	private StringBuffer elementBuffer = new StringBuffer();

	@SuppressWarnings("unchecked")
	private HashMap attributeMap;
	private Document doc;

	public Document getDocument(InputStream is) throws DocumentHandlerException {

		SAXParserFactory spf = SAXParserFactory.newInstance();
		try {
			SAXParser parser = spf.newSAXParser();
			parser.parse(is, this);
		} catch (IOException e) {
			throw new DocumentHandlerException("Cannot parse XML document", e);
		} catch (ParserConfigurationException e) {
			throw new DocumentHandlerException("Cannot parse XML document", e);
		} catch (SAXException e) {
			throw new DocumentHandlerException("Cannot parse XML document", e);
		}
		return doc;
	}

	@Override
	public void startDocument() {
		doc = new Document();
	}

	@Override
	@SuppressWarnings("unchecked")
	public void startElement(String uri, String localName, String qName,
			Attributes atts) throws SAXException {
		elementBuffer.setLength(0);
		if(attributeMap != null)
			attributeMap.clear();
		else
			attributeMap = new HashMap();
		if (atts.getLength() > 0) {
			for (int i = 0; i < atts.getLength(); i++) {
				attributeMap.put(atts.getQName(i), atts.getValue(i));
			}
		}
	}

	@Override
	public void characters(char[] text, int start, int length) {
		elementBuffer.append(text, start, length);
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if (qName.equals("address-book")) {
			return;
		} else if (qName.equals("contact")) {
			Iterator<?> iter = attributeMap.keySet().iterator();
			while (iter.hasNext()) {
				String attName = (String) iter.next();
				String attValue = (String) attributeMap.get(attName);
				doc.add(new Field(attName, attValue, Field.Store.YES, Field.Index.ANALYZED));
				// doc.add(Field.Keyword(attName, attValue));
			}
		} else {
			// doc.add(Field.Keyword(qName, elementBuffer.toString()));
			doc.add(new Field(qName, elementBuffer.toString(), Field.Store.YES, Field.Index.ANALYZED));
		}
	}
}
